package com.caiwangdai.app.widget


import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.ImageFormat
import android.graphics.Matrix
import android.hardware.Camera
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.Surface
import android.view.SurfaceHolder
import android.view.SurfaceView
import com.caiwangdai.app.backend.rx.RxSchedulers
import com.caiwangdai.app.utils.FileUtils
import com.orhanobut.logger.Logger
import io.reactivex.Observable
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream


class CameraView : SurfaceView, SurfaceHolder.Callback {

    constructor(context: Context) : super(context, null, 0)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle)

    companion object {
        val CAMERA_BACK = 0
        val CAMERA_FRONT = 1

        val CAMERA_TYPE_CARD = 0
        val CAMERA_TYPE_FACE = 1;
    }

    val TAG = "weimu"
    var currentCamera = CAMERA_BACK//当前摄像头  0为后置  1为前置
    var cameraType = CAMERA_TYPE_CARD//0为身份证 1为人脸

    var mCamera: Camera? = null
    var mSurfaceHolder: SurfaceHolder? = null


    init {
        isClickable = true
        mSurfaceHolder = this.holder
        mSurfaceHolder?.addCallback(this)
        mSurfaceHolder?.setKeepScreenOn(true)// 屏幕常亮
    }

    //检查设备是否支持摄像头
    private fun CheckCameraHardware(mContext: Context): Boolean {
        val isExist = mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
        return isExist
    }


    override fun onTouchEvent(event: MotionEvent): Boolean {
        val action = event.action
        when (action) {
            MotionEvent.ACTION_UP -> autoFocus()

        }
        return super.onTouchEvent(event)
    }

    fun onResume() {
        if (CheckCameraHardware(context)) {
            try {
                mCamera = Camera.open(currentCamera)
                initCameraParam()
            } catch (e: Exception) {
                Log.d("TAG", "Error is " + e.message)
            }
        }
        setCameraDisplayOrientation(context as Activity, currentCamera, mCamera)
    }

    fun onPause() {
        closeCamera()
    }

    fun initCameraParam() {
        val params = mCamera!!.parameters
        params.pictureFormat = ImageFormat.JPEG
        params.focusMode = Camera.Parameters.FOCUS_MODE_AUTO
        params.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE
        params.sceneMode = Camera.Parameters.SCENE_MODE_AUTO
        val PreviewSizesMode1 = params.supportedPreviewSizes.filter { (it.height.toFloat() / it.width.toFloat()) == (9f / 16f) }
        val PreviewSizesMode2 = params.supportedPreviewSizes.filter { (it.height.toFloat() / it.width.toFloat()) == (9f / 12f) }


//        for (item in PreviewSizesMode1) {
//            Log.e("weimu", "预览尺寸 16x9 =" + item.width + "x" + item.height);
//        }
//        Log.e("weimu", "-----------");
        val picSizeMode1 = params.supportedPictureSizes.filter { (it.height.toFloat() / it.width.toFloat()) == (9f / 16f) }
        val picSizeMode2 = params.supportedPictureSizes.filter { (it.height.toFloat() / it.width.toFloat()) == (9f / 12f) }
//        for (item in picSizeMode1) {
//            Log.e("weimu", "照片尺寸 16x9 =" + item.width + "x" + item.height);
//        }
//        Log.e("weimu", "-----------");
//        for (item in PreviewSizesMode2) {
//            Log.e("weimu", "预览尺寸 4x3 =" + item.width + "x" + item.height);
//        }
//        Log.e("weimu", "-----------");
//        for (item in picSizeMode2) {
//            Log.e("weimu", "照片尺寸 4x3 =" + item.width + "x" + item.height);
//        }
        var targetWidth = 0
        var targetHeight = 0;
        if (cameraType == CAMERA_TYPE_CARD) {
            //身份证
            targetWidth = PreviewSizesMode1[0].width
            targetHeight = PreviewSizesMode1[0].height
            params.setPreviewSize(targetWidth, targetHeight)
            params.setPictureSize(targetWidth, targetHeight)

        } else {
            //头像
            targetWidth = PreviewSizesMode2[0].width
            targetHeight = PreviewSizesMode2[0].height
            params.setPreviewSize(targetWidth, targetHeight)

            targetWidth = picSizeMode2[picSizeMode2.size - 4].width
            targetHeight = picSizeMode2[picSizeMode2.size - 4].height

            params.setPictureSize(targetWidth, targetHeight)
        }

        try {
            mCamera!!.parameters = params
            Log.e("weimu", "相机设置参数 成功")
        } catch (exception: Exception) {
            exception.printStackTrace()
        }
        startPreviewDisplay(holder)
    }

    //对焦
    fun autoFocus() {
        mCamera?.autoFocus(null)
    }

    fun takePicture() {
        mCamera?.takePicture(null, null, mPicureCallback)
    }

    //有的摄像头不支持
    fun takeAutoPicture() {
        mCamera?.autoFocus { isSuccess, camera ->
            if (isSuccess && camera != null) {
                mCamera!!.takePicture(null, null, mPicureCallback)
            }
        }
    }

    //开启
    override fun surfaceCreated(surfaceHolder: SurfaceHolder) {
        //todo 依然存在问题
//        val canvas = surfaceHolder.lockCanvas(null)
//        canvas.drawColor(ContextCompat.getColor(context, R.color.gray_background))
//        surfaceHolder.unlockCanvasAndPost(canvas)

        startPreviewDisplay(surfaceHolder)
    }

    //改变
    override fun surfaceChanged(surfaceHolder: SurfaceHolder, i: Int, i1: Int, i2: Int) {
        setCameraDisplayOrientation(context as Activity, currentCamera, mCamera)
        stopPreviewDisplay()
        startPreviewDisplay(mSurfaceHolder!!)
    }


    //销毁
    override fun surfaceDestroyed(surfaceHolder: SurfaceHolder) {
        stopPreviewDisplay()
    }


    private fun startPreviewDisplay(holder: SurfaceHolder) {
        mCamera?.setPreviewDisplay(holder)
        mCamera?.startPreview()
    }

    fun stopPreviewDisplay() {
        mCamera?.stopPreview()
    }


    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        closeCamera()
    }


    private val mPicureCallback = Camera.PictureCallback { mData, camera -> savePicToSdCard(mData) }

    private fun savePicToSdCard(mData: ByteArray) {

        Observable.create<File> { e ->
            val mPictureFile = FileUtils.getIDCardOutputFile(FileUtils.MEDIA_TYPE_IMAGE)
            val orientation = resources.configuration.orientation

            var bMap: Bitmap = BitmapFactory.decodeByteArray(mData, 0, mData.size)
            var bMapRotate: Bitmap? = null

            if (orientation == Configuration.ORIENTATION_PORTRAIT) {
                val matrix = Matrix()
                matrix.reset()
                if (currentCamera == 0) {
                    matrix.postRotate(90f)
                } else {
                    matrix.postRotate(-90f)
                }
                bMapRotate = Bitmap.createBitmap(bMap, 0, 0, bMap.width, bMap.height, matrix, true)
                bMap = bMapRotate
            }

            val bos = BufferedOutputStream(FileOutputStream(mPictureFile))
            bMap.compress(Bitmap.CompressFormat.JPEG, 80, bos)//将图片压缩到流中
            bos.flush()//输出
            bos.close()//关闭

            if (bMapRotate != null && !bMapRotate.isRecycled) {
                bMapRotate.recycle()
            }

            if (!bMap.isRecycled) {
                bMap.recycle()
            }
            e.onNext(mPictureFile)
            e.onComplete()

        }.compose(RxSchedulers.toMain())
                .subscribe { b ->
                    stopPreviewDisplay()
                    onCameraStatusListener?.onCameraStopped(b.toString())
                }
    }


    private fun closeCamera() {
        mCamera?.cancelAutoFocus()
        mCamera?.stopPreview()
        mCamera?.release()
        mCamera = null
    }


    var onCameraStatusListener: OnCameraStatusListener? = null

    /**
     * 相机拍照监听接口
     */
    interface OnCameraStatusListener {

        // 相机拍照结束事件
        fun onCameraStopped(url: String)

        // 拍摄时自动对焦事件
        fun onAutoFocus(success: Boolean)

        // 触摸屏幕对焦事件
        fun onTouchFocus(mCamera: Camera)
    }


    fun followScreenOrientation(context: Context, camera: Camera) {
        val orientation = context.resources.configuration.orientation
        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
            camera.setDisplayOrientation(180)
        } else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
            camera.setDisplayOrientation(90)
        }
    }


    fun setCameraDisplayOrientation(activity: Activity, cameraId: Int, camera: Camera?) {
        if (camera == null) return
        // See android.hardware.Camera.setCameraDisplayOrientation for
        // documentation.
        val info = Camera.CameraInfo()
        Camera.getCameraInfo(cameraId, info)
        val degrees = getDisplayRotation(activity)
        var result: Int
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360
            result = (360 - result) % 360 // compensate the mirror
        } else { // back-facing
            result = (info.orientation - degrees + 360) % 360
        }
        camera.setDisplayOrientation(result)
    }

    fun getDisplayRotation(activity: Activity): Int {
        val rotation = activity.windowManager.defaultDisplay.rotation
        when (rotation) {
            Surface.ROTATION_0 -> return 0
            Surface.ROTATION_90 -> return 90
            Surface.ROTATION_180 -> return 180
            Surface.ROTATION_270 -> return 270
        }
        return 0
    }
}
